<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>打字练习与考试系统-练习</title>
    <link rel="shortcut icon" href="favicon.ico">
    
    <style>
    /* body{text-align:center} */
    div.header
    {
        width:800px;
        margin:0 auto;
        text-align: center;
    }

    /* ul li以横排显示 */
    div.menu
    {
        width:100%;
        float:left;
        background-color: #465c71; /* 背景色 */
        text-align:center;
        margin-bottom:10px;
    }
    /* 所有class为menu的div中的ul样式 */
    div.menu ul
    {
        list-style:none; /* 去掉ul前面的符号 */
        margin:0 auto; /* 与外界元素的距离为0 */
        padding: 0px; /* 与内部元素的距离为0 */
        width: 400px; /* 宽度根据元素内容调整 */
        float:center;
    }
    /* 所有class为menu的div中的ul中的li样式 */
    div.menu ul li
    {
        float:left; /* 向左漂移，将竖排变为横排 */
    }
    /* 所有class为menu的div中的ul中的a样式(包括尚未点击的和点击过的样式) */
    div.menu ul li a, div.menu ul li a:visited
    {
        background-color: #465c71; /* 背景色 */
        border: 1px #4e667d solid; /* 边框 */
        color: #dde4ec; /* 文字颜色 */
        display: block; /* 此元素将显示为块级元素，此元素前后会带有换行符 */
        line-height: 1.35em; /* 行高 */
        padding: 4px 20px; /* 内部填充的距离 */
        text-decoration: none; /* 不显示超链接下划线 */
        white-space: nowrap; /* 对于文本内的空白处，不会换行，文本会在在同一行上继续，直到遇到 <br> 标签为止。 */
    }
    /* 所有class为menu的div中的ul中的a样式(鼠标移动到元素中的样式) */
    div.menu ul li a:hover
    {
        background-color: #bfcbd6; /* 背景色 */
        color: #465c71; /* 文字颜色 */
        text-decoration: none; /* 不显示超链接下划线 */
    }
    /* 所有class为menu的div中的ul中的a样式(鼠标点击元素时的样式) */
    div.menu ul li a:active
    {
        background-color: #465c71; /* 背景色 */
        color: #cfdbe6; /* 文字颜色 */
        text-decoration: none; /* 不显示超链接下划线 */
    }


    footer{
        width: 100%;
        height:50px;   /* footer的高度一定要是固定值*/
        position:absolute;
        bottom:10px;
        left:0px;
        background: #333;
        text-align:center;
        margin : 10px;
    }

    .content{
        text-align: center;
    }

    *{
        margin: 0;
        padding: 0;
    }
    .type_content{
        width: 60%;
        /* height: 440px; */
        border: 1px solid #ccccff;
        max-width: 600px;
        margin: 10px auto;
        border-radius: 8px;
        position: relative;
        min-width: 500px;
    }
    .type_content h3{
        text-align: center;
        margin: 10px 0px;
    }
    .type_box{
        list-style: none;
        width: 90%;
        height: 100px;
        /* border: 1px solid black; */
        margin: 0 auto;
        margin-bottom: 10px;
       display: flex;
       align-items: center;
       justify-content: space-around;
    }
    .type_box li{
        width: 88px;
        height: 88px;
        /* border: 1px solid black; */
        text-align: center;
        font-size: 16px;
        border-radius: 8px;
        /* color: #fff; */
    }
    .error_box{
        background-color: #ccffcc;
        color: red;
    }
    .time_box{
        background-color: #66ffff;
        color: #000033;
    }
    .currcorrect_box{
        background-color: #FFC125;
        color: #fff;
    }
    .type_speed{
        background-color: #FF4040;
        color: #fff;
        display: block;
    }
    .final_correct{
        background-color: #E3E3E3;
        color: #555555;
        display: none;
    }
    .error{
        margin: 10px;
    }
    .text_box{
        width: 80%;
        /* height: 50px; */
        margin: 20px auto 20px auto;
        /* border: 1px solid black; */
        background-color: #D1EEEE;
        color: #000;
        border-radius: 6px;
        text-align: left;
        line-height: 40px;
        padding: 6px 5px;
        font-size: 18px;
        /* box-sizing: border-box; */
    }
    .text_area{
        width: 80%;
        height: 300px;
        margin: 0px auto;
        padding-bottom: 50px;
        margin-bottom: 30px;
    }
    #textarea_box{
        resize:none;
        width: 100%;
        height: 100%;
        padding: 6px 5px;
        font-size: 16px;
        border-radius: 6px;
        outline: none;
        border: none;
        border: 2px solid #eee;
    }
    .incorrect_char {
        color: red;
        text-decoration: underline;
      }

      .correct_char {
        color: #9B30FF;
      }
      .restart{
          width: 120px;
          height: 40px;
          display: none;
          border: none;
          outline: none;
          cursor: pointer;
          color: #fff;
          background-color: #9900ff;
          border-radius: 6px;
          position: absolute;
          bottom: 10px;
          left: 50%;
          margin-left: -60px;
      }
      .start{
          width: 120px;
          height: 40px;
          display: block;
          border: none;
          outline: none;
          cursor: pointer;
          color: #fff;
          background-color: #9900ff;
          border-radius: 6px;
          position: absolute;
          bottom: 10px;
          left: 50%;
          margin-left: -60px;
      }
      .clear{
        clear:both;
       }

       [v-cloak]{
            display: none;
        }
    </style>

</head>
<!-- oncontextmenu="return false" -->
<body class="gray-bg" onselectstart="return false" oncopy="alert('对不起，禁止复制！');return false;" onpaste="return false;">
<div class="header"><a href="/"><h1>打字练习与考试系统</h1></a></div>
<div class="menu">
    <ul>
        <li><a href="/" style="background-color:red">练习</a></li>
        <li><a href="/exam">考试</a></li>
        <li><a href="/status">状态</a></li>
        <li><a href="/paiming">排名</a></li>
        <li><a href="/student">学生</a></li>
    </ul>
</div>
<div class="clear"></div>
<div id="app" v-cloak> 
    <div class="content">
        <div>
            教育局
            <select v-model="jiaoyuju" @change="selectJiaoyuju()" :disabled="started">
                <option v-for="jiaoyuju in jiaoyujus" :value="jiaoyuju.deptId">{{jiaoyuju.deptName}}</option>
            </select>
            集团校
            <select v-model="jituanxiao"  @change="selectJituanxiao()"  :disabled="started">
                <option v-for="jituanxiao in jituanxiaos" :value="jituanxiao.deptId">{{jituanxiao.deptName}}</option>
            </select>
            学校
            <select v-model="school"  :disabled="started">
                <option v-for="school in schools" :value="school.deptId">{{school.deptName}}</option>
            </select>
            年级
            <select v-model="nianji"  :disabled="started">
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
                <option value="4">4</option>
                <option value="5">5</option>
                <option value="6">6</option>
                <option value="7">7</option>
                <option value="8">8</option>
                <option value="9">9</option>
            </select>
            班级
            <select v-model="banji"  :disabled="started">
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
                <option value="4">4</option>
                <option value="5">5</option>
                <option value="6">6</option>
                <option value="7">7</option>
                <option value="8">8</option>
                <option value="9">9</option>
                <option value="10">10</option>
                <option value="11">11</option>
                <option value="12">12</option>
                <option value="13">13</option>
                <option value="14">14</option>
                <option value="15">15</option>
                <option value="16">16</option>
                <option value="17">17</option>
                <option value="18">18</option>
                <option value="19">19</option>
                <option value="20">20</option>
                <option value="21">21</option>
                <option value="22">22</option>
                <option value="23">23</option>
                <option value="24">24</option>
                <option value="25">25</option>
                <option value="26">26</option>
                <option value="27">27</option>
                <option value="28">28</option>
                <option value="29">29</option>
                <option value="30">30</option>
            </select>
            姓名：<input id="username" v-model="username" value=""  :disabled="started"/>
        </div>
        <div>
            测试类型：
            <label for="radio_en">
                <input name="type" type="radio" id="radio_en" value="en" checked="checked" v-on:click="setLeibie('英文打字')"  :disabled="started">
                英文打字
            </label>
            <label for="radio_cn">
                <input type="radio" name="type" id="radio_cn" value="cn" v-on:click="setLeibie('中文打字')"  :disabled="started">
                中文打字
            </label>
        </div>
        <div v-show="!started">
            选择文章：{{selectedArticle.title}}
            <a href="javascript:;" v-on:click="select_art_show()" id="select_b">选择</a>
            <div class="ul" v-for="article in articles" v-show="show">
                <a class="sys" href="javascript:;" v-on:click="select_art(article)">{{ article.title }}</a>
                <div class="clear"></div>
            </div>
        </div>
        <div class="clear"></div>
        <div>
            <button v-on:click="start()" v-show="!started">开始测试</button>
        </div>
        <div class="clear"></div>
    </div>
    <div class="type_content" v-show="started">
        <h3>打字练习</h3>
        <ul class="type_box">
            <li class="error_box">
                <p class="error">错误</p>
                <p class="error_text">{{error_text}}</p>
            </li>
            <li class="time_box">
                <p style="margin: 10px;">时间</p>
                <p class="time_text">{{timeLeft}}s</p>
            </li>
            <li class="currcorrect_box">
                <p style="margin: 10px;">准确率%</p>
                <p class="currcorrect_text">{{currcorrect}}</p>
            </li>
            <li class="type_speed">
                <p style="margin: 10px;">打字速度</p>
                <p class="type_speed_text">{{speed}}个/分</p>
            </li>
        </ul>
        <div class="text_box">点击下方文本输入框开始打字！！！</div>
        <div class="text_area">
        <textarea name="" id="textarea_box"  placeholder="在此开始打字" v-model="textarea_box"
            v-on:input="processCurrentText()"
            v-on:click="startGame()"
            > </textarea>
        </div>
        <button class="restart" onclick="resetValues()">重新开始</button>
    </div>
</div>

<footer>
    <a href="/admin">后台管理</a>
</footer>

<script th:src="@{/js/vue.min.js}"></script>
<script th:src="@{/js/axios.min.js}"></script>

<script type="text/javascript">
    var app = new Vue({
      el: '#app',
      data: {
        jiaoyujus:[],
        jiaoyuju:0,
        jituanxiaos:[],
        jituanxiao:0,
        schools:[],
        school:'',
        articles:[],
        leibie:'',
        show:false,
        selectedArticle:{title:''},
        username:'',
        nianji:'',
        banji:'',
        started:false,
        gameIsStart:false,
        /* 打字测试js*/
        error:0,
        currcorrect:0,
        speed:0,
        testTime: 300,
        timeLeft : 300,
        testSentence : [
            "Push yourself, because no one else is going to do it for you.",
            "Failure is the condiment that gives success its flavor.",
            //"Wake up with determination. Go to bed with satisfaction.",
            // "It's going to be hard, but hard does not mean impossible.",
            // "Learning never exhausts the mind.",
            // "The only way to do great work is to love what you do."
        ],
        //当前句子
        currentSentence : "",
        //默认开始是索引为0
        startIndex : 0,
        //错误统计
        errors : 0,
        characterTyped : 0,
        total_characterTyped: 0,
        //总错误
        total_errors : 0,
        error_text: 0,
        timer : null,
        timeElapsed : 0, //已用时间
        accuracy : 0,//正确个数
        textarea_box:''
      },
      mounted:function(){
          this.setLeibie('英文打字');
          this.listJiaoyuju();
      },
      methods:{
        selectJituanxiao(){
            var _this = this;
            var data = {parentId:this.jituanxiao};
            axios.post('/listSysDept',JSON.stringify(data),
                    {headers: {'content-type': 'application/json'}}
                ).then(function(res){
                    _this.schools = res.data;
            },function(){
                console.log('请求失败处理');
            });
        },
        selectJiaoyuju(){
            var _this = this;
            var data = {parentId:this.jiaoyuju};
            axios.post('/listSysDept',JSON.stringify(data),
                    {headers: {'content-type': 'application/json'}}
                ).then(function(res){
                    _this.jituanxiaos = res.data;
            },function(){
                console.log('请求失败处理');
            });
        },
        listJiaoyuju(){
            var _this = this;
            var data = {parentId:100};
            axios.post('/listSysDept',JSON.stringify(data),
                    {headers: {'content-type': 'application/json'}}
                ).then(function(res){
                    _this.jiaoyujus = res.data;
                    console.log(_this.jiaoyujus);
            },function(){
                console.log('请求失败处理');
            });
        },
        setLeibie:function(leibie){
            this.leibie = leibie;
            this.listArticle()
        },
        listArticle:function(){
            var _this = this;
            var data = {leibie:this.leibie};
            axios.post('/listArticle',JSON.stringify(data),
                    {headers: {'content-type': 'application/json'}}
                ).then(function(res){
                    _this.articles = res.data.rows;
                    // res.data.rows.forEach((item)=>{
                    //     _this.articles.push(item);
                    // });
                    //console.log(_this.articles);
            },function(){
                console.log('请求失败处理');
            });
        },
        select_art_show:function(){
            this.show = true;
        },
        select_art:function(article){
            this.show = false;
            this.selectedArticle=article;
        },
        start:function(article){
            if(this.jiaoyuju == "")
            {
                alert("请先选择教育局");
                return;
            }
            if(this.jituanxiao == "")
            {
                alert("请先选择集团校");
                return;
            }
            if(this.school == "")
            {
                alert("请先选择学校");
                return;
            }
            if(this.nianji == "")
            {
                alert("请先选择年级");
                return;
            }
            if(this.banji == "")
            {
                alert("请先选择班级");
                return;
            }
            if(this.username == "")
            {
                alert("请先输入姓名");
                return;
            }
            if(this.selectedArticle.title == "")
            {
                alert("请先选择文章");
                return;
            }
            var checkStudentExist = [[${@config.getKey('sys.student.checkStudentExist')}]];
            if(checkStudentExist){
                let data = { 
                    nianji:this.nianji,
                    banji:this.banji,
                    name:this.username,
                    jiaoyujuId:this.jiaoyuju,
                    jituanxiaoId:this.jituanxiao,
                    schoolId:this.school,
                };
                var _this = this;
                axios.post('/typing/student/checkStudentExist',JSON.stringify(data),
                    {headers: {'content-type': 'application/json'}}
                ).then(function(res){
                    if(res.data.code == 0){
                        _this.started = true;
                        _this.testSentence = _this.selectedArticle.content.split('\n');
                        _this.testSentence.push("");
                    }
                    else{
                        alert(res.data.msg);
                    }
                },function(){
                    console.log('请求失败处理');
                });
            }else{
                this.started = true;
                this.timeLeft = this.testTime;
                this.testSentence = this.selectedArticle.content.split('\n');
                this.testSentence.push("");
            }
        },
        startGame:function(){
            if(this.gameIsStart==false)
            {
                this.gameIsStart = true;
                this.resetValues();
                this.updateSentence();
                // clear old and start a new timer
                clearInterval(this.timer);
                this.timer = setInterval(this.updateTimer, 1000);
            }  
        },
        //输入当前正确的句子
        processCurrentText:function(){
            curr_input = this.textarea_box;
            curr_input_array = curr_input.split('');
            // console.log(curr_input_array);
            this.characterTyped=0;
            this.errors = 0;
            let text_box = document.querySelector('.text_box');
            quoteSpanArray = text_box.querySelectorAll('span');
            // console.log(quoteSpanArray);
            quoteSpanArray.forEach((char,index)=>{
                var typeChar = curr_input_array[index];
                //当前没有输入
                if(typeChar == null){
                    char.classList.remove('correct_char');
                    char.classList.remove('incorrect_char');
                }else if(typeChar === char.innerText){
                    this.characterTyped++;
                    //正确的输入
                    char.classList.add('correct_char');
                    char.classList.remove('incorrect_char');
                }else{
                    this.characterTyped++;
                    //不正确的输入
                    char.classList.add('incorrect_char');
                    char.classList.remove('correct_char');
                    this.errors++;
                }
            })
            this.error_text = this.total_errors + this.errors;

            var correctCharacters = this.total_characterTyped + this.characterTyped - (this.total_errors + this.errors);
            var accuracyVal = correctCharacters / (this.total_characterTyped + this.characterTyped) * 100;
            if(isNaN(accuracyVal))
                accuracyVal=0;
            this.currcorrect = Math.round(accuracyVal.toFixed(2));
            cpm = Math.round(((correctCharacters / this.timeElapsed) * 60));
            this.speed = cpm;

            //输入结束
            if(curr_input.length == this.currentSentence.length){
                this.updateSentence();
                this.total_errors += this.errors;
                this.total_characterTyped += this.characterTyped;
                this.textarea_box = ""
            }
        },
        //更新渲染句子
        updateSentence:function(){
            var text_box = document.querySelector('.text_box');
            text_box.textContent = null;
            this.currentSentence = this.testSentence[this.startIndex];
            //句子拆分
            var newChar = this.currentSentence.split('');
            for(var i = 0; i < newChar.length; i++){
                var charSpan = document.createElement('span');
                charSpan.innerText = newChar[i];
                text_box.appendChild(charSpan)
            }
            if(this.startIndex < this.testSentence.length - 1){
                this.startIndex++;
            }else{
                this.finishGame();
            }
        },
        //更新时间
        updateTimer: function() {
            //console.log(this.timeLeft)
            if (this.timeLeft > 0) {
                // decrease the current time left
                this.timeLeft--;

                // increase the time elapsed
                this.timeElapsed++;
            }
            else {
                // finish the game
                this.finishGame();
            }
        },
        finishGame: function() {
            // stop the timer
            clearInterval(this.timer);

            // disable the input area
            var textarea_box = document.querySelector('#textarea_box');
            textarea_box.disabled = true;
            this.textarea_box = "";

            // show finishing text
            var text_box = document.querySelector('.text_box');
            text_box.textContent = "";

            var correctCharacters = this.total_characterTyped + this.characterTyped - (this.total_errors + this.errors);
            var accuracyVal = correctCharacters / (this.total_characterTyped + this.characterTyped) * 100;
            if(isNaN(accuracyVal))
                accuracyVal=0;
            this.currcorrect = Math.round(accuracyVal.toFixed(2));
            cpm = Math.round(((correctCharacters / this.timeElapsed) * 60));
            this.speed = cpm;

            this.save(this.username,this.currcorrect,this.speed);
        },
        //重新开始
        resetValues: function(){
            this.timeLeft = this.testTime;
            this.timeElapsed = 0;
            this.errors = 0;
            this.total_errors = 0;
            this.accuracy = 0;
            this.characterTyped = 0;
            this.startIndex = 0;
            // textarea_box.disabled = false;
            // textarea_box.value = "";
            // text_box.textContent = '点击下方文本输入框开始打字！！！';
            // currcorrect_text.textContent = 100;
            // time_text.textContent = timeLeft + 's';
            //type_speed.style.display = 'none';
        },
        save:function(){
            if(this.currcorrect < 90)
            {
                alert("本次准确率小于90%，成绩无效,不会保存成绩。");
                return ;
            }
            if(this.speed < 5)
            {
                alert("速度小于5，成绩无效,不会保存成绩。");
                return ;
            }
            var _this = this;
            let data = { nianji:this.nianji,banji:this.banji,name:this.username,accuracy:this.currcorrect,speed:this.speed,
                articleId:this.selectedArticle.articleId,
                title:this.selectedArticle.title,
                testTime:this.testTime,
                leibie:this.leibie,
                model:'练习',
                jiaoyujuId:this.jiaoyuju,
                jituanxiaoId:this.jituanxiao,
                schoolId:this.school,
            };
            //console.log(data);
            axios.post('/add',JSON.stringify(data),
                    {headers: {'content-type': 'application/json'}}
                ).then(function(res){
                    console.log(res.data);
                    if(res.data.code == 0)
                        alert("成绩保存成功！")
            },function(){
                console.log('请求失败处理');
            });
        }
      }
    })
</script>

</body>
</html>
